﻿using System;
using System.Collections.Generic;
using System.IO;
using Amba.Workflow.Services;
using Orchard.Forms.Services;
using Orchard.Localization;
using Orchard.Workflows.Models;
using Orchard.Workflows.Services;

namespace Amba.Workflow.Activities
{
    public class PeriodicalEvent : Event
    {
        private readonly IPeriodicalEventService _periodicalEventService;

        public PeriodicalEvent(IPeriodicalEventService periodicalEventService)
        {
            _periodicalEventService = periodicalEventService;
        }

        public Localizer T { get; set; }

        public override bool CanStartWorkflow
        {
            get { return true; }
        }

        public override string Form
        {
            get { return "PeriodicEventForm"; }
        }

        public override string Name
        {
            get { return "PeriodicalEvent"; }
        }

        public override Orchard.Localization.LocalizedString Category
        {
            get { return T("Scheduler"); }
        }

        public override Orchard.Localization.LocalizedString Description
        {
            get { return T("Runs periodicaly"); }
        }

        public override IEnumerable<Orchard.Localization.LocalizedString> GetPossibleOutcomes(Orchard.Workflows.Models.WorkflowContext workflowContext, Orchard.Workflows.Models.ActivityContext activityContext)
        {
            return new[] { T("Done") };
        }

        public override IEnumerable<Orchard.Localization.LocalizedString> Execute(Orchard.Workflows.Models.WorkflowContext workflowContext, Orchard.Workflows.Models.ActivityContext activityContext)
        {
            yield return T("Done");
        }

        public override bool CanExecute(WorkflowContext workflowContext, ActivityContext activityContext)
        {
            File.AppendAllText(@"d:\temp\test_activity.txt", "check " + DateTime.Now.ToString() + Environment.NewLine);
            var amount = activityContext.GetState<int>("Amount");
            var type = activityContext.GetState<string>("Unity");
            if (amount < 1 || string.IsNullOrEmpty(type))
                return false;

            var record = _periodicalEventService.GetPeriodicalEventInfo(activityContext.Record.Id);

            var nextRun = GetNextRun(record.LastRun, amount, type);
            if (nextRun > DateTime.UtcNow)
                return false;
            _periodicalEventService.SetLastRunDate(activityContext.Record.Id);
            return true;
        }

        public static DateTime GetNextRun(DateTime lastRun, int amount, string type)
        {
            try
            {
                var when = lastRun;
                switch (type)
                {
                    case "Minute":
                        when = when.AddMinutes(amount);
                        break;
                    case "Hour":
                        when = when.AddHours(amount);
                        break;
                    case "Day":
                        when = when.AddDays(amount);
                        break;
                    case "Week":
                        when = when.AddDays(7 * amount);
                        break;
                    case "Month":
                        when = when.AddMonths(amount);
                        break;
                    case "Year":
                        when = when.AddYears(amount);
                        break;
                }

                return when;
            }
            catch
            {
                return DateTime.MaxValue;
            }
        }
    }
}